java并发知识点
前言
先列出java并发涉及的知识点,后面再慢慢补.
java并发
1 常见概念
进程/线程
- 进程:程序执行的实体,操作系统资源调度资源分配的基本单元
- 线程:程序执行的最小单元,拥有独立的堆栈和局部变量等属性,可以共享进程的资源
同步(Synchronous)/异步(Asynchronous)
- 同步是串行执行,阻塞
- 异步是并行执行,非阻塞
并发/并行
- 并发:多个任务交替执行
- 并行:多个任务同时执行
临界区
阻塞(Blocking)/非阻塞(Non-Blocking)
死锁/饥饿/活锁
JMM(java内存模型)
- 可见性
- 原子性
- 有序性
并发级别
- 阻塞(加锁阻塞)
- 无饥饿(公平锁实现无饥饿)
- 无锁(CAS)
- 无等待(Read-Copy-Update)
2 多线程基础
线程状态
- New:新建
- Runnable:运行中
- Blocked:阻塞, 等待锁是blocked
- Waiting:等待,Object.wait/Condition.await操作释放锁,线程进入等待状态
- Time-Waiting:超时等待, sleep()操作,不会释放锁
- Terminated:结束
基本操作
- 新建:Thread/Runnable
- 终止:stop(废弃)/interrupt
- 等待(wait)/通知(notify),必须配合Synchronous使用
- 挂起(suspend)/只需执行(resume),已废弃
- 等待线程结束join
- 谦让yield
- 优先级priority
线程池
Excutor
ExcutorService扩展Excutor
ThreadPoolExcutor线程池对象
Executors线程池工厂,返回指定类型的线程池对象
原理:
1线程池对象的构造函数:
- corePoolSize:线程池中的线程数量
- maximumPoolSize:线程池最大线程数量
- keepAliveTime:超过corePoolSize数量额线程的存活时间
- unit:时间单位
- workQueue:任务队列,有界队列:ArrayBlockingQueue/无界队列:LinkedBlockingQueue
- handler:拒绝策略
2线程池工厂:ThreadFactory,使用该工厂创建线程
3 锁
synchronized
- 原理:在JVM编译后,在入口处加上Monitorenter指令,结束位置或异常处加上monitorexit的指令;
- 作用:保证了JMM的三个特性:原子性/可见性(unlock之前保证变量会同步到主内存中去)/有序性(变量同一时刻只能由一个线程处理)
Lock/ReentrantLock
- 细粒度的锁,有lock()/unlock()/trylock操作;
- 可以实现公平锁和非公平锁(默认)
- 原理:AQS
volatile
- 保证可见性,不保证原子性
- 禁止指令重排序保证有序性
ThreadLocal
保存的数据可以看作线程内部局部变量;
实现:实现:当前线程有个ThreadLocalMap表,存储着当前ThreadLocal实例和对应的value;
乐观锁CAS(compare and swap)
synchronized和lock是悲观锁,CAS就是乐观锁
实现:修改数据时,需要三个参数:内存地址,旧的值,新的值, 只有旧的值等于当前内存地址中保存的值,才会更新为新的值
jvm对锁的优化:
- 锁消除:jvm会判断加锁的代码是否真的需要加锁,如果不需要会执行不加锁操作;
- 自旋锁:竞争锁失败后不会立即被挂起(线程的挂起需要操作系统配合,耗费资源),而是类似有个while(true)循环多少次后再去竞争锁;
- 偏向锁:同一个线程重复访问一个同步代码块时,可以直接获取到锁,免去了CAS加锁解锁的操作,使用锁竞争少的场景;
- 轻量级锁:
- 重量级锁
提高锁性能的建议
- 减少锁持有的时间
- 减少锁粒度
- 锁分离:读写锁
- 锁的粗化:频繁加锁释放锁也是不小的开销,粗化减少加锁次数
4 JUC并发包
Condition
Semaphore信号量
ReadWriteLock读写锁
CountDownLatch倒计时器
CycliBarrier栅栏
LockSupport线程阻塞工具
Fork/join
AQS(AbstractQueuedSynchronized)并发基础组件
并发容器
- 线程安全的Map:ConcurrentMap
- 线程安全的List:CopyOnWriteArrayList
- 高效队列ConcurrentLinkedQueue
- 阻塞队列BlockingQueue
- 双向队列Deque
- 随机数据结构SkipList